/**
 * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022-2023. All rights reserved.
 *
 * Description: Application core main function for standard \n
 *
 * History: \n
 * 2022-07-27, Create file. \n
 */

#include "lwip/nettool/misc.h"
#include "lwip/ip4_addr.h"
#include "lwip/netif.h"
#include "lwip/netifapi.h"
#include "lwip/sockets.h"

#include "cmsis_os2.h"
#include "ohos_init.h"
#include "soc_osal.h"
#include "wifi_connect.h"

#define UDP_CLIENT_TASK_PRIO                  (osPriority_t)(13)
#define UDP_CLIENT_TASK_DURATION_MS           2000
#define UDP_CLIENT_TASK_STACK_SIZE            0x1000

#define CONFIG_WIFI_SSID            "MY_SW"                              // 要连接的WiFi 热点账号
#define CONFIG_WIFI_PWD             "12345678"                        // 要连接的WiFi 热点密码
 #define CONFIG_SERVER_IP            "192.168.43.228"                     // 要连接的服务器IP
//#define CONFIG_SERVER_IP            "192.168.43.151"                     // 要连接的服务器IP

#define CONFIG_SERVER_PORT          3861                                // 要连接的服务器端口

static const char *send_data = "Hello! I'm UDP Client!\r\n";
int sock_fd = -1;

int udp_send_data(uint8_t *data,int datalen){
    if(sock_fd < 0){
        return;
    }
    struct sockaddr_in send_addr;
    socklen_t addr_length = sizeof(send_addr);
      // 初始化预连接的服务端地址
    send_addr.sin_family = AF_INET;
    send_addr.sin_port = htons(CONFIG_SERVER_PORT);
    send_addr.sin_addr.s_addr = inet_addr(CONFIG_SERVER_IP);
    addr_length = sizeof(send_addr);

    //  bzero(recvBuf, sizeof(recvBuf));

    // 发送数据到服务远端
    osal_printk("sendto start!\r\n");
    int n = sendto(sock_fd, data, datalen, 0, (struct sockaddr *)&send_addr, addr_length);
    osal_printk("sendto end!\r\n");
    
    return n;
}

int udp_client_sample_task(void *param)
{
    param = param;

    // 在sock_fd 进行监听，在 new_fd 接收新的链接
    

    // 服务器的地址信息
    struct sockaddr_in send_addr;
    struct sockaddr_in server_sock;
    socklen_t addr_length = sizeof(send_addr);
    char recvBuf[512];

    // 连接Wifi
    wifi_connect(CONFIG_WIFI_SSID, CONFIG_WIFI_PWD);

    // 创建socket
    osal_printk("create socket start!\r\n");
    if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        osal_printk("create socket failed!\r\n");
        return 0;
    }
    osal_printk("create socket end!\r\n");
    // 初始化预连接的服务端地址
    bzero(&server_sock, sizeof(server_sock));
	server_sock.sin_family = AF_INET;
	server_sock.sin_addr.s_addr = htonl(INADDR_ANY);
	server_sock.sin_port = htons(3861);

	//调用bind函数绑定socket和地址
	if (bind(sock_fd, (struct sockaddr *)&server_sock, sizeof(struct sockaddr)) == -1)
	{
		perror("bind is error.\r\n");
		return -1;
	}

    while (1) {
        bzero(recvBuf, sizeof(recvBuf));

        // // 接收服务端返回的字符串
        recvfrom(sock_fd, recvBuf, sizeof(recvBuf), 0, (struct sockaddr *)&send_addr, &addr_length);
        osal_printk("%s:%d=>%s\n", inet_ntoa(send_addr.sin_addr), ntohs(send_addr.sin_port), recvBuf);
        //将收到的数据转发给客户端
        uart_sle_client_send_data(recvBuf,strlen(recvBuf));
    }

    // 关闭这个 socket
    lwip_close(sock_fd);
    return 0;
}
static void udp_client_sample_entry(void)
{
    osThreadAttr_t attr;
    attr.name       = "udp_client_sample_task";
    attr.attr_bits  = 0U;
    attr.cb_mem     = NULL;
    attr.cb_size    = 0U;
    attr.stack_mem  = NULL;
    attr.stack_size = UDP_CLIENT_TASK_STACK_SIZE;
    attr.priority   = UDP_CLIENT_TASK_PRIO;
    if (osThreadNew((osThreadFunc_t)udp_client_sample_task, NULL, &attr) == NULL) {
        osal_printk("Create udp_client_sample_task fail.\r\n");
    }
    osal_printk("Create udp_client_sample_task succ.\r\n");
}

/* Run the udp_client_sample_task. */
SYS_RUN(udp_client_sample_entry);